Collecting performance-related information during the execution of programs has become an important part of program code optimization. Hardware-level monitoring collects information at the micro-architectural level such as the number of instructions executed, the number of cache misses, the number of mis-predicted branches, etc.
Contemporary processors typically include a Performance Monitoring Unit (PMU) that provides support for collecting the above information by exporting a set of programmable counters. However, the PMU can change significantly from one processor implementation to another and sometimes inside the same processor family. For example, in the Itanium® Processor Family, the number of events that can be measured goes from about 200 for Itanium® to about 500 for Itanium® 2. Events with the same name are not necessarily encoded the same way. The width of the counters goes from 32 bits to 47 bits between the two generations of processor. In addition, the functionality of each PMU model may vary greatly. Many PMU models go beyond just providing simple counters, many can capture addresses, latencies and branches for example. Similarly, monitoring tools have very different needs depending on what they measure, from collecting simple system-wide counts to collecting counts for individual tasks across multiple processors. Typically, a monitoring tool can receive desired performance data if it provides a specific (“raw”) event code for the PMU of the given target CPU.